#include <cv.h>
#include <highgui.h>
#include <stdio.h>
#include <math.h>
#include "config.h"

static const char* wndimg   = "img"  ;
static const char* wndgray  = "gray" ;
static const char* wndred   = "red"  ;
static const char* wndgreen = "green";
static const char* wndblue  = "blue" ;
static const char* wnddisplayred   = "displayred"  ;
static const char* wnddisplaygreen = "displaygreen";
static const char* wnddisplayblue  = "displayblue" ;

int test3(int argc, char** argv)
{
	int numImage;
	int dp =3;
	int dist = 10;
	int diamMin = 1;
	int diamMax;
	int p1 = 75;
	int p2 = 40;
	int pfiltre = 3;
	IplImage* img;
	IplImage* gray;
	IplImage* red;
	IplImage* green;
	IplImage* blue;
	IplImage* displayred;
	IplImage* displaygreen;
	IplImage* displayblue;
    CvMemStorage* storagegray;
    CvMemStorage* storagered;
    CvMemStorage* storagegreen;
    CvMemStorage* storageblue;
    CvSeq* circlesgray;
    CvSeq* circlesred;
    CvSeq* circlesgreen;
    CvSeq* circlesblue;
	printf("<test3> : debut de la fonction\n");
    cvNamedWindow( wndimg  , 2);
    cvNamedWindow( wndgray , 2);
    cvNamedWindow( wndred  , 2);
    cvNamedWindow( wndgreen, 2);
    cvNamedWindow( wndblue , 2);
    cvNamedWindow( wnddisplayred  , 2);
    cvNamedWindow( wnddisplaygreen, 2);
    cvNamedWindow( wnddisplayblue , 2);
	cvMoveWindow(wndimg  ,1200,  500);
	cvMoveWindow(wndgray ,1200, 250);
	cvMoveWindow(wndred  ,   0, 250);
	cvMoveWindow(wndgreen, 300, 250);
	cvMoveWindow(wndblue , 600, 250);
	cvMoveWindow(wnddisplayred  ,   0, 500);
	cvMoveWindow(wnddisplaygreen, 300, 500);
	cvMoveWindow(wnddisplayblue , 600, 500);
    for( numImage = 0; names[numImage] != 0; numImage++ )
    {
		char nomImage[40] = "";
        int touche;
		strcat(nomImage, folder);
		strcat(nomImage, names[numImage]);
    	img = cvLoadImage( nomImage, 1 );
        if( !img )
        {
            printf("<test3> Couldn't load %s\n", names[numImage] );
            continue;
        }
        diamMax = (MAX(img->width,img->height))/25;
        gray  = cvCreateImage( cvGetSize(img), IPL_DEPTH_8U, 1 );
        red   = cvCreateImage( cvGetSize(img), IPL_DEPTH_8U, 1 );
        green = cvCreateImage( cvGetSize(img), IPL_DEPTH_8U, 1 );
        blue  = cvCreateImage( cvGetSize(img), IPL_DEPTH_8U, 1 );
        displayred   = cvCloneImage( img );
        displaygreen = cvCloneImage( img );
        displayblue  = cvCloneImage( img );
        storagegray  = cvCreateMemStorage(0);
        storagered   = cvCreateMemStorage(0);
        storagegreen = cvCreateMemStorage(0);
        storageblue  = cvCreateMemStorage(0);
        printf("<test3> cvCreateImage OK\n" );
        
        cvCvtColor( img, gray, CV_BGR2GRAY );
        cvCvtPixToPlane(img, red, green, blue, 0);
        
        cvSmooth( gray , gray , CV_GAUSSIAN, pfiltre, pfiltre, 0, 0 );
        cvSmooth( red  , red  , CV_GAUSSIAN, pfiltre, pfiltre, 0, 0 );
        cvSmooth( green, green, CV_GAUSSIAN, pfiltre, pfiltre, 0, 0 );
        cvSmooth( blue , blue , CV_GAUSSIAN, pfiltre, pfiltre, 0, 0 );
        
        circlesgray  = cvHoughCircles( gray , storagegray , CV_HOUGH_GRADIENT, dp, dist, p1, p2, diamMin, diamMax);
        circlesred   = cvHoughCircles( red  , storagered  , CV_HOUGH_GRADIENT, dp, dist, p1, p2, diamMin, diamMax);
        circlesgreen = cvHoughCircles( green, storagegreen, CV_HOUGH_GRADIENT, dp, dist, p1, p2, diamMin, diamMax);
        circlesblue  = cvHoughCircles( blue , storageblue , CV_HOUGH_GRADIENT, dp, dist, p1, p2, diamMin, diamMax);
        
        int i;
        for( i = 0; i < circlesgray->total; i++ )
        {
             float* p = (float*)cvGetSeqElem( circlesgray, i );
             cvCircle( img, cvPoint(cvRound(p[0]),cvRound(p[1])), 3            , CV_RGB(0,255,0), -1, 8, 0 );
             cvCircle( img, cvPoint(cvRound(p[0]),cvRound(p[1])), cvRound(p[2]), CV_RGB(255,0,0),  3, 8, 0 );
        }
        for( i = 0; i < circlesred->total; i++ )
        {
             float* p = (float*)cvGetSeqElem( circlesred, i );
             cvCircle( displayred, cvPoint(cvRound(p[0]),cvRound(p[1])), 3            , CV_RGB(0,255,0), -1, 8, 0 );
             cvCircle( displayred, cvPoint(cvRound(p[0]),cvRound(p[1])), cvRound(p[2]), CV_RGB(255,0,0),  3, 8, 0 );
        }
        for( i = 0; i < circlesgreen->total; i++ )
        {
             float* p = (float*)cvGetSeqElem( circlesgreen, i );
             cvCircle( displaygreen, cvPoint(cvRound(p[0]),cvRound(p[1])), 3            , CV_RGB(0,255,0), -1, 8, 0 );
             cvCircle( displaygreen, cvPoint(cvRound(p[0]),cvRound(p[1])), cvRound(p[2]), CV_RGB(255,0,0),  3, 8, 0 );
        }
        for( i = 0; i < circlesblue->total; i++ )
        {
             float* p = (float*)cvGetSeqElem( circlesblue, i );
             cvCircle( displayblue, cvPoint(cvRound(p[0]),cvRound(p[1])), 3            , CV_RGB(0,255,0), -1, 8, 0 );
             cvCircle( displayblue, cvPoint(cvRound(p[0]),cvRound(p[1])), cvRound(p[2]), CV_RGB(255,0,0),  3, 8, 0 );
        }
        
        cvShowImage( wndimg  , img  );
        cvShowImage( wndgray , gray );
        cvShowImage( wndimg  , img  );
        cvShowImage( wndgray , gray );
        cvShowImage( wndred  , red  );
        cvShowImage( wndgreen, green);
        cvShowImage( wndblue , blue );
        cvShowImage( wnddisplayred  , displayred  );
        cvShowImage( wnddisplaygreen, displaygreen);
        cvShowImage( wnddisplayblue , displayblue );
        
        touche = cvWaitKey(0);
        
        cvReleaseImage( &img   );
        cvReleaseImage( &gray  );
        cvReleaseImage( &red   );
        cvReleaseImage( &green );
        cvReleaseImage( &blue  );
        cvReleaseImage( &displayred  );
        cvReleaseImage( &displaygreen);
        cvReleaseImage( &displayblue );
        cvClearMemStorage( storagegray  );
        cvClearMemStorage( storagered   );
        cvClearMemStorage( storagegreen );
        cvClearMemStorage( storageblue  );
        if( (char)touche == 27 )
            break;
    }
    cvDestroyWindow( wndimg   );
    cvDestroyWindow( wndgray  );
    cvDestroyWindow( wndred   );
    cvDestroyWindow( wndgreen );
    cvDestroyWindow( wndblue  );
    //cvDestroyWindow( wndother );
    cvDestroyWindow( wnddisplayred   );
    cvDestroyWindow( wnddisplaygreen );
    cvDestroyWindow( wnddisplayblue  );
    return 0;
}